﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Ria.ApplicationServices;
using System.Windows.Ria.Data;
using System.Windows.Shapes;
using AlexApp;
using ExpenseReport;

namespace UserControls
{
    /// <summary>
    /// Login Control that allows a user to login and logout and displays the users name.
    /// </summary>
    public partial class LoginControl : UserControl
    {
        private ExpenseReportApp parentApp = null;
        private LoginChildWindow loginWindow = null;
        private ExpenseData domainContext = null;

        public LoginControl()
        {
            InitializeComponent();

            domainContext = new ExpenseData();

            CheckLoginStatus();
            UserService.Current.LoginCompleted +=
                new EventHandler<LoginCompletedEventArgs>(UserService_LoginCompleted);
            UserService.Current.LogoutCompleted += 
                new EventHandler<LogoutCompletedEventArgs>(UserService_LogoutCompleted);
        }
        
        /// <summary>
        /// Helper property that creates a LoginChild window if one hasn't been created.
        /// </summary>
        private LoginChildWindow LoginWindow
        {
            get
            {
                if (loginWindow == null)
                {
                    loginWindow = new LoginChildWindow();
                    loginWindow.userIdTextBox.TextChanged += new TextChangedEventHandler(userIdTextBox_TextChanged);
                    loginWindow.loginFormButton.Click += new RoutedEventHandler(loginFormButton_Click);
                    loginWindow.cancelFormButton.Click += new RoutedEventHandler(cancelFormButton_Click);
                }
                return loginWindow;
            }
        }

        /// <summary>
        /// Check to see if current user is logged in an set the visual state of the control.
        /// </summary>
        public void CheckLoginStatus()
        {
            User user = UserService.Current.User as User;
            this.LoginButton.IsEnabled = true;

            //Find parent application for navigation.
            UIElement element = this;
            while (element != null && element.GetType() != typeof(ExpenseReportApp))
            {
                element = (UIElement)(VisualTreeHelper.GetParent(element));
            }
            if (element != null)
            {
                parentApp = element as ExpenseReportApp;
            }

            if (user != null && user.IsAuthenticated)
            {
                LoginButton.Content = "Logout";
                LoginWindow.Close();
                WelcomeText.Visibility = Visibility.Visible;

                //User is authenticated so get the current user's name.
                domainContext.Loaded += new EventHandler<LoadedDataEventArgs>(domainContext_Loaded);
                domainContext.LoadEmployees(ExpenseData.EmployeesQuery.Where(e => e.employee == UserService.Current.User.Name),null);

                if (element != null && parentApp != null && parentApp.myFrame != null)
                {
                    parentApp.myFrame.Navigate(new Uri("/ExpenseReportSummary.xaml", UriKind.Relative));

                }
            }
            else if (user == null && parentApp != null && parentApp.myFrame != null)
            {
                parentApp.myFrame.Navigate(new Uri("/Instructions.xaml", UriKind.Relative));
            }
        }

        /// <summary>
        /// Responds to loaded event from DomainContext and sets the value of TextBlock to the employee's name. 
        /// </summary>
        /// <param name="sender">DomainContext</param>
        /// <param name="e">LoadedDataEventArgs for Loaded event</param>
        void domainContext_Loaded(object sender, LoadedDataEventArgs e)
        {
            domainContext.Loaded += new EventHandler<LoadedDataEventArgs>(domainContext_Loaded);
            Employee emp = (Employee)e.LoadedEntities.FirstOrDefault();
            UserIdTextBlock.Text = emp.Name;
        }

        /// <summary>
        /// Validates that users was correctly authenticated and updates visual elements.
        /// </summary>
        /// <param name="sender">UserService</param>
        /// <param name="e">LoginCompletedEventArgs for LoginCompleted event</param>
        private void UserService_LoginCompleted(object sender, LoginCompletedEventArgs e)
        {
            User user = UserService.Current.User as User;

            CheckLoginStatus();

            if (user != null && !user.IsAuthenticated)
            {
                loginWindow.statusMessage.Text = "Login Failed please try again.";
                loginWindow.userIdTextBox.Text = "";
                loginWindow.passwordTextBox.Password = "";
                WelcomeText.Visibility = Visibility.Collapsed;
                UserIdTextBlock.Text = "";
            }
        }

        /// <summary>
        /// Responds to LogoutEvent and updates visual elements.
        /// </summary>
        /// <param name="sender">UserService</param>
        /// <param name="e">LogoutCompletedEventArgs for LogoutCompleted event</param>
        void UserService_LogoutCompleted(object sender, LogoutCompletedEventArgs e)
        {
            LoginButton.Content = "Login";
            WelcomeText.Visibility = Visibility.Collapsed;
            UserIdTextBlock.Text = "";
            User currentUser = UserService.Current.User as User;
            if (currentUser != null & !currentUser.IsAuthenticated && parentApp != null)
            {
                parentApp.myFrame.Navigate(new Uri("/Instructions.xaml", UriKind.Relative));

            }
        }

        /// <summary>
        /// Based on state of login button either logs out the user or shows the login window.
        /// </summary>
        /// <param name="sender">LoginButton</param>
        /// <param name="e">RoutedEventArgs for button's click event.</param>
        private void LoginButton_Click(object sender, RoutedEventArgs e)
        {
            if (String.Compare(LoginButton.Content.ToString(), "Login")==0)
            {
                LoginWindow.Show();
            }
            else
            {
                UserService.Current.Logout();
            }
        }
 
        /// <summary>
        /// Updates that status message when new text is entered for User ID
        /// </summary>
        /// <param name="sender">User ID textbox</param>
        /// <param name="e">TextChangedEventArgs for user ID textbox</param>
        void userIdTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            //If user types in text then clear status message.
            TextBox textBox = (TextBox)sender;
            if (textBox != null && textBox.Text != "")
            {
                loginWindow.statusMessage.Text = "";
            }
        }

        /// <summary>
        /// Reacts to Login button clicked on LoginChildWindow.  
        /// </summary>
        /// <param name="sender">Login button</param>
        /// <param name="e">RoutedEventArgs for Login button click.</param>
        void loginFormButton_Click(object sender, RoutedEventArgs e)
        {
            if (UserService.Current.IsBusy)
            {
                loginWindow.statusMessage.Text = "Please wait for login to complete.";
            }
            else
            {
                UserService.Current.Login(new
                    System.Windows.Ria.ApplicationServices.LoginParameters(
                       loginWindow.userIdTextBox.Text, loginWindow.passwordTextBox.Password));
            }
        }

        /// <summary>
        /// Reacts to Cancel button clicked on LoginChildWindow.  
        /// </summary>
        /// <param name="sender">Cancel button</param>
        /// <param name="e">RoutedEventArgs for Cancel button click.</param>
        void cancelFormButton_Click(object sender, RoutedEventArgs e)
        {
            LoginWindow.Close();
        }

    }
}
